﻿namespace GoodAdmin.System;

public class ExtraOrgService : IExtraOrgService, ITransient
{
    private readonly IBaseService _baseService;
    private readonly ISysOrgService _sysOrgService;
    private readonly IFileService _fileService;
    private readonly ISysImportErrorListService _importErrorListService;

    public ExtraOrgService(IBaseService baseService, ISysOrgService sysOrgService,
        IFileService fileService,
        ISysImportErrorListService importErrorListService)
    {
        _baseService = baseService;
        _sysOrgService = sysOrgService;
        _fileService = fileService;
        _importErrorListService = importErrorListService;
    }
    /// <inheritdoc />
    public async Task AddOrg(OrgAddInput input)
    {
        await CheckDataScope(input.ParentId);
        await _sysOrgService.AddOrg(input);
    }

    /// <inheritdoc/>
    public async Task<ExcelImportResult> ImportOrg(IFormFile file)
    {
        var sysFile = await _fileService.UploadFile(file, FileConst.BatchImport);
        var columnList = UtilMethod.GetEntityMetadataToList<OrgBatchAdd>();
        var importData = await ExcelImportHelper.ReadExcelToList<OrgBatchAdd>(Path.Combine(sysFile.EnginePath, sysFile.StoragePath), columnList);
        var (orgList,errorList) = await CheckImportAuthority(importData);
        var addErrorList = await _sysOrgService.BatchAddOrg(orgList);

        errorList.AddRange(addErrorList);
        var errorCount = addErrorList.Count;
        var message = $"成功导入{importData.Count - errorCount}条数据，失败{errorCount}条数据";
        var excelImportResult = new ExcelImportResult() { ErrorCount = errorCount, FileName = "组织批量导入错误记录.xlsx", Message = message, IsHasErrorFile = errorCount > 0 };
        if (errorCount > 0)
        {
            SysImportErrorList importErrorList = new() { ErrorList = addErrorList.ToJson(), MethodName = nameof(ImportOrg) };
            excelImportResult.ListId = await _importErrorListService.Save(importErrorList);
        }
        return excelImportResult;
    }

    /// <inheritdoc/>
    public FileStreamResult TemplateDownload()
    {
        string fileName = "组织信息导入模板";

        ExcelConfig excelconfig = new()
        {
            FileName = fileName,
            HeadFont = "微软雅黑",
            HeadPoint = 10,
            IsAllSizeColumn = true,
            ColumnHeaderModel = new List<ExcelColumnHeaderModel>(),
            ColumnModel = new List<ExcelColumnModel>()
        };
        var columnList = UtilMethod.GetEntityMetadataToList<OrgBatchAdd>();
        foreach (var item in columnList)
        {
            //如果列名是*开头，表示必填，红色字体显示
            excelconfig.ColumnHeaderModel.Add(new ExcelColumnHeaderModel()
            {
                Column = item.FieldName,
                ExcelColumn = item.Comment,
                ForeColor = item.Comment.StartsWith("*") ? IndexedColors.Red : IndexedColors.Black

            });
            excelconfig.ColumnModel.Add(new ExcelColumnModel() 
            { 
                Column = item.FieldName,
                ExcelColumn = item.Comment 
            });
        }

        FileStreamResult stream = ExcelExportHelper<OrgBatchAdd>.Export(new List<OrgBatchAdd>(), excelconfig, fileName);
        return stream;
    }

    public async Task<FileStreamResult> ErrorDownload(BaseIdInput input)
    {
        var importErrorList = await _importErrorListService.GetById(input.Id);
        try
        {
            var errorList = importErrorList.ErrorList.ToList<OrgBatchAddOutput>();
            var columnList = UtilMethod.GetEntityMetadataToList<OrgBatchAddOutput>();
            string fileName = "组织导入错误记录.xlsx";
            ExcelConfig excelconfig = new()
            {
                FileName = fileName,
                HeadFont = "微软雅黑",
                HeadPoint = 10,
                IsAllSizeColumn = true,
                ColumnHeaderModel = new List<ExcelColumnHeaderModel>(),
                ColumnModel = new List<ExcelColumnModel>(),
                Title = "错误记录"
            };
            foreach (var item in columnList)
            {
                //如果列名是*开头，表示必填，红色字体显示
                excelconfig.ColumnHeaderModel.Add(new ExcelColumnHeaderModel()
                {
                    Column = item.FieldName,
                    ExcelColumn = item.Comment,

                });
                excelconfig.ColumnModel.Add(new ExcelColumnModel() 
                { 
                    Column = item.FieldName, 
                    ExcelColumn = item.Comment, 
                    ForeColor = item.Comment.StartsWith("*") ? IndexedColors.Red : null 
                });
            }
            FileStreamResult stream = ExcelExportHelper<OrgBatchAddOutput>.Export(errorList, excelconfig, fileName);
            return stream;
        }
        catch (Exception)
        {

            throw;
        }
    }
    /// <inheritdoc />
    public async Task DeleteOrg(BaseIdInput input)
    {
        await CheckDataScope(input.Id);
        await _sysOrgService.DeleteOrg(input);
    }
    /// <inheritdoc />
    public async Task<SqlSugarPagedList<SysOrg>> GetOrgPageList(OrgPageInput input)
    {
        if (!UserManager.SuperAdmin)
        {
            var dataScope = await _baseService.GetUserApiRoleOrgIdByRequest();
            input.DataScope = dataScope;
        }
        return await _sysOrgService.GetOrgPageList(input);
    }
    /// <inheritdoc />
    public async Task<List<OrgSimpleInfo>> GetOrgTree()
    {
        List<long> dataScope = null;
        if (!UserManager.SuperAdmin)
        {
            dataScope = await _baseService.GetUserApiRoleOrgIdByRequest();
        }
        return await _sysOrgService.GetOrgTree(dataScope);
    }
    /// <inheritdoc />
    public async Task UpdateOrg(OrgUpdateInput input)
    {
        //当前组织信息（更新前）
        var sysOrg = await _sysOrgService.GetOrgDetail(input.Id);
        var checkOrgIds= new List<long> { input.Id };
        //如果改变了上级组织，那么也需要验证是否有上级组织权限
        if (sysOrg.ParentId != input.ParentId)
        {
            checkOrgIds.Add(input.ParentId);
        }        
        await _baseService.CheckDataScope(checkOrgIds);
        await _sysOrgService.UpdateOrg(input);
    }

    /// <summary>
    /// 检查数据范围
    /// </summary>
    /// <param name="OrgId"></param>
    /// <returns></returns>
    private async Task CheckDataScope(long OrgId)
    {
        await _baseService.CheckDataScope(OrgId);
    }

    /// <summary>
    /// 检查导入数据是否有权限添加
    /// </summary>
    /// <param name="importData"></param>
    /// <returns></returns>
    private async Task<(List<OrgBatchAdd>, List<OrgBatchAddOutput>)> CheckImportAuthority(List<OrgBatchAdd> importData)
    {
        if (importData.Count == 0)
        {
            throw Oops.Bah(OrgErrorCode.O009);
        }
        List<OrgBatchAddOutput> errorList = new();
        var dataScope = await _baseService.GetUserApiRoleByRequest();
        //如果是超级管理员，或者数据范围类型为所有组织，那么直接返回
        if (UserManager.SuperAdmin  || dataScope.ScopeType==RoleConst.DATA_SCOPE_ALL) return(importData, errorList);

        //检查数据范围权限        
        var sysOrgs = await _sysOrgService.GetOrgList();        
        List<OrgBatchAdd> orgList = new();
        var sortData = importData.OrderBy(x => x.LongName);
        foreach (var item in sortData)
        {
            var errorMessage = string.Empty;
            //去除组织名称中的空格和末尾可能存在的">"
            string orgName = item.LongName.Replace(" ", "").TrimEnd(">").TrimStart(">");
            int lastIndex = orgName.LastIndexOf('>');
            string parentName = lastIndex != -1 ? orgName.Substring(0, lastIndex) : "";
            //导入数据中有当前组织的上级组织，并且上级组织没有权限错误
            if (orgList.Any(it => it.LongName == parentName))
            {
                if (errorList.Any(it => it.LongName == parentName))
                {
                    errorMessage += "无权限添加该组织;";
                }
            }
            else if (sysOrgs.Any(it => it.LongName == parentName))
            {
                var parentId = sysOrgs.First(it => it.LongName == parentName).Id;
                //数据范围为自定义、本部门、自己的，都无权限添加新组织
                if(dataScope.ScopeType==RoleConst.DATA_SCOPE_DEFINE || dataScope.ScopeType==RoleConst.DATA_SCOPE_OWNORG || dataScope.ScopeType == RoleConst.DATA_SCOPE_SELF)
                {
                    errorMessage += "无权限添加该组织;";
                }
                else if (!dataScope.OrgList.Contains(parentId))
                {
                    errorMessage += "无权限添加该组织;";
                }
            }
            
            if (!string.IsNullOrEmpty(errorMessage))
            {
                var errorItem = item.Adapt<OrgBatchAddOutput>();
                errorItem.ErrorMessages = errorMessage;
                errorList.Add(errorItem);
            }
            else
            {
                orgList.Add(item);
            }
        }
        return (orgList, errorList);
    }
}